package com.abprogramming.controller;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class EditController {
    @FXML
    private File path;

    @FXML
    private BorderPane rootPane;

    //TopController
    @FXML
    private MenuBar menuBar;
    @FXML

    private Menu file;
    @FXML
    private MenuItem newBuilt;
    @FXML
    private MenuItem open;

    @FXML
    private MenuItem save;
    @FXML
    private MenuItem saveAs;
    @FXML
    private MenuItem exit;

    @FXML
    private Menu edit;
    @FXML
    private MenuItem copy;
    @FXML
    private MenuItem stick;

    @FXML
    private Menu help;

    @FXML
    private Menu isSave;

    @FXML
    private Menu runBox;

    @FXML
    private MenuItem run;

    @FXML
    private void handlerExit(ActionEvent event){
        Platform.exit();
    }

    @FXML
    private void handlerNewBuilt(){
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter(".java", "*.java");
        fileChooser.getExtensionFilters().add(filter);
        path = fileChooser.showSaveDialog(rootPane.getScene().getWindow());
        try {
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(path));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void handlerOpen(ActionEvent event){
        textArea.setText("");
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter(".java", "*.java");
        fileChooser.getExtensionFilters().add(filter);
        path = fileChooser.showOpenDialog(rootPane.getScene().getWindow());
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8));
            String line = null;
            while ((line = reader.readLine()) != null) {
                textArea.appendText(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @FXML
    private void handlerSave(){
        if (path != null){
            BufferedWriter out = null;
            try {
                out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path),StandardCharsets.UTF_8));
                out.write(textArea.getText());
                isSave.setText("已保存");
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (out != null){
                    try {
                        out.flush();
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }else {
            handlerNewBuilt();
        }
    }

    @FXML
    private void handlerSaveAs(){
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter(".java", "*.java");
        fileChooser.getExtensionFilters().add(filter);
        File saveAsPath = fileChooser.showSaveDialog(rootPane.getScene().getWindow());
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(saveAsPath),StandardCharsets.UTF_8));
            out.write(textArea.getText());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out != null){
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @FXML
    private void compileCode(){
        Runtime runtime = Runtime.getRuntime();
        try {
            Process process = runtime.exec("cmd.exe /c javac " + path);
            if (process.waitFor() == 0){
                process.destroy();
                runCode();
            }else {
                String errPut = getStreamStr(process.getErrorStream(),"GBK");
                console.setText("控制台输出：\n" + errPut);
            }
            process.destroy();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void runCode(){
        Runtime runtime = Runtime.getRuntime();

        String classPath = path.toString().substring(0,path.toString().lastIndexOf("\\"));
        String className = path.toString().substring(path.toString().lastIndexOf("\\") + 1, path.toString().lastIndexOf("."));
        try {
            Process process = runtime.exec("cmd.exe /c java -cp " + classPath + " " + className);
            String outPut = getStreamStr(process.getInputStream(),"UTF-8");
            String errPut = getStreamStr(process.getErrorStream(),"GBK");
            if ("".equals(errPut)){
                console.setText("控制台输出：\n" + outPut);
            }else {
                console.setText("控制台输出：\n" + errPut);
            }
            process.destroy();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getStreamStr(InputStream inputStream, String code){
        StringBuilder sb = new StringBuilder();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(inputStream, code));
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
                sb.append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

    //CenterController
    @FXML
    private TextArea textArea;

    @FXML
    private void handlerChangeValue(KeyEvent event){
        isSave.setText("未保存");
    }

    //Bottom
    @FXML
    private TextArea console;

    @FXML
    private Button clear;

    @FXML
    private void handlerClearConsole(){
        console.setText("控制台输出：");
    }

    @FXML
    private void keySave(KeyEvent event){
        if ("s".equals(event.getText())){
            handlerSave();
        }
    }

}
